
package Lexico;

import Mensajes.Mensaje;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Observable;
import FileManager.ManejadorArchivo;
import TablaDeSimbolos.TSimbolo;
import TokensDelLenguaje.Tokens;
import TokensDelLenguaje.Token;

public class AnalizadorLexico extends Observable {

    Object [][] ME;

    int contador_lineas;
    int estado;
    boolean marcar_caracter;
    AccionSemantica procesar;
    ManejadorArchivo ma;
    int estados[][];
    int procesos[][];
    
    public AnalizadorLexico(ManejadorArchivo ma, TSimbolo tabla_simbolo) throws FileNotFoundException{
        this.ma = ma;
        ma.abrir_archivo();
        this.contador_lineas = 1;
        estado = 0;
        marcar_caracter = true;
        procesar = new AccionSemantica(ma, this, tabla_simbolo);
    }

    public Token obtener_token() throws FileNotFoundException, IOException{
        int cod_char, cod_proc;
        char car_entrada;
        cod_char = 0;
        Token t;
        while(cod_char != -1){
            cod_char = ma.obtener_cod_sig_caracter(marcar_caracter);
            marcar_caracter = true;
            car_entrada = ma.traducir_a_caracter(cod_char);
            int i = Clasificador.getId(car_entrada).ordinal();
            cod_proc = procesos[estado][Clasificador.getId(car_entrada).ordinal()];
            estado = estados[estado][Clasificador.getId(car_entrada).ordinal()];
            if(estado == -1){
                estado = 0;
                t= procesar.ejecutarASemantica(car_entrada, cod_proc);
                if(t != null && t.getId() != Tokens.ilegal)
                    return t;
                else
                    continue;
            }
            procesar.ejecutarASemantica(car_entrada, cod_proc);
        }
        ma.cerrar_archivo();
        return new Token(Tokens.eof);
    }

    public void incrementar_num_lineas(){
        contador_lineas++;
    }

    public void decrementar_num_lineas(){
        contador_lineas--;
    }

    public int get_num_lineas(){
        return contador_lineas;
    }

    public void marcar_caracter(boolean marcar) {
      marcar_caracter = marcar;
    }

    public char obtener_caracter(boolean marcar) throws IOException {
      return (char)ma.obtener_cod_sig_caracter(marcar);
    }

    public void informe(String inf, int tipo) {
      Mensaje msj = new Mensaje("ERROR LEXICO: " + inf, Mensaje.INF);
      setChanged();
      notifyObservers(msj);
    }

    public int[][] getME(){

        return this.estados;
    }
    public int [][] getMP(){
        return this.procesos;
    }

    public void setMTE(int[][] estados) {
        this.estados=estados;
    }

    public void setMTP(int[][] procesos) {
        this.procesos=procesos;
    }
}
